package com.finance.system.service;

import com.alibaba.dubbo.common.utils.StringUtils;
import com.finance.framework.lang.Page;
import com.finance.framework.lang.PageResultBO;
import com.finance.base.enums.StateEnum;
import com.finance.base.exception.BaseException;
import com.finance.system.bean.pojo.Menu;
import com.finance.system.dao.MenuMapper;
import com.finance.system.dao.RoleMapper;
import com.finance.util.MenuUtil;
import com.finance.system.bean.pojo.Role;
import com.finance.system.bean.pojo.User;
import com.finance.system.bean.pojo.UserRoleRel;
import com.finance.system.dao.UserMapper;
import com.finance.system.dao.UserRoleMapper;
import com.finance.util.encrypt.EncryptUtil;
import org.apache.commons.collections.CollectionUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;

/**
 * Created by CBWL on 2017/3/9.
 */
@Service("userService")
public class UserService implements IUserService{
    Logger logger = LoggerFactory.getLogger(this.getClass());

    @Resource
    private UserMapper userMapper;
    @Resource
    private UserRoleMapper userRoleMapper;
    @Autowired
    private RoleMapper roleMapper;
    @Autowired
    private MenuMapper menuMapper;


    /**
     * 验证密码
     * @param user
     * @param passwd
     * @return
     */
    @Override
    public boolean verifyPass(User user,String passwd){
        if(user == null) {
            return false;
        }
        String val = "";
        try{
            val = EncryptUtil.encryptBASE64(EncryptUtil.md5(passwd,"UTF-8").getBytes("UTF-8"));
        }catch (Exception e){
            logger.error("未知加密算法错误");
        }
        return val.equals(user.getPasswd());
    }

    /**
     * 角色匹配
     * @param user
     * @param roleId
     * @return
     */
    @Override
    public boolean hasRole(User user, String roleId) {
        if(user != null && StringUtils.isNotEmpty(roleId)){
            if(CollectionUtils.isNotEmpty(user.getRoleList())){
                if(user.getRoleList().size() > 0 ){
                    for(Role role : user.getRoleList()){
                        if(role != null && role.getId() !=0){
                            if(role.getId().toString().equals(roleId)){
                                return true;
                            }
                        }
                    }
                }
            }
        }
        return false;
    }

    /**
     * 获取菜单tree
     * @param u
     * @return
     */
    @Override
    public Menu getMenuTree(User u) {
        return this.fillMenuTree(u);
    }

    /**
     * 填充菜单tree
     * @param u
     * @return
     */
    private Menu fillMenuTree(User u) {
        StringBuilder roleId = new StringBuilder() ;
        for (Role role : u.getRoleList()){
//            List<Map<String,Object>> roleMapList = this.roleMapper.getByRoleId(role.getId());
//            if(roleMapList != null && roleMapList.size() >0) {
//                for (Map roleMap : roleMapList) {
//                    Menu menu = new Menu();
//                    menu.setName((String) roleMap.get("menuName"));
//                    menu.setUrl((String) roleMap.get("url"));
//                    menu.setCode((String) roleMap.get("menuCode"));
//                    menu.setPCode((String) roleMap.get("pCode"));
//                    menu.setType((Integer) roleMap.get("type"));
//                    menu.setState((Integer) roleMap.get("menuState"));
//                    menusList.add(menu);
//                }
//            }
//            role.setMenuList(menusList);
            roleId.append(",").append("'").append(role.getId()).append("'");
        }
        List<Menu> menusList = this.menuMapper.getMenuByRoleId(roleId.deleteCharAt(0).toString());
        return MenuUtil.MenuTree(menusList);
    }

    @Override
    @Deprecated
    public User getById(Long id) {
        User user = this.userMapper.getById(id);
        return user;
    }

    /**
     * 根据工号查询用户
     * @param code
     * @return
     */
    @Override
    @Cacheable(value="setting",cacheResolver = "settingCacheResolver",key="'uid_'+ #code")
    public User getByCode(String code){
        User user = this.userMapper.getByCode(code);
        return user;
    }

    @Override
    @Deprecated
    public User getByIdWithLock(Long id) {
        User user = this.userMapper.getByIdWithLock(id);
        return user;
    }

    /**
     * 根据手机号查询用户
     * @param mobile
     * @return
     */
    @Override
    @Cacheable(value="setting",cacheResolver = "settingCacheResolver",key="'umb_'+#mobile")
    public User getByMobile(String mobile){
        User user = this.userMapper.getByMobile(mobile);
        return user;
    }

    /**
     * 分页查询用户
     * @param page
     * @return
     */
    @Override
    public PageResultBO<User> listByPage(Page page) {
        PageResultBO<User> resultBO = new PageResultBO<User>();
        List<User> list = this.userMapper.listByPage(page);
        resultBO.setDataList(list);
        resultBO.setPageSize(page.getPageSize());
        resultBO.setPageNo(page.getPageNo());
        resultBO.setTotalRecord(page.getTotalRecord());
        return resultBO;
    }

    /**
     * 更新用户
     * @param user
     * @param code
     * @return
     */
    @Override
    @Transactional
    @CacheEvict(value="setting",cacheResolver = "settingCacheResolver",key="'uid_'+ #code")
    public User update(User user, Long uId, List<Long> roleIds, String code)throws BaseException {
        boolean backResult = this.updateRoleRel(user.getCode(),uId,roleIds);
        if(backResult){
            backResult = this.userMapper.update(user) == 1;
        }
        if(backResult){
            this.userMapper.getByCode(user.getCode());
        }
        return null;
    }

    /**
     * 新增用户
     * @param user
     * @return
     */
    @Override
    @Transactional
    public boolean add(User user,List<Long> roleIds) throws BaseException {
        boolean backResult = true;
        if(roleIds != null && roleIds.size() >0){
            backResult = this.addUserRole(user.getCode(),user.getCreateUid(),roleIds);
        }
        return this.userMapper.add(user) == 1 && backResult;
    }

    /**
     * 删除用户
     * @param id
     * @return
     */
    @Override
    public boolean delete(String id) throws BaseException {
        return this.userMapper.delete(id)==1;

    }

    /**
     * 批量删除用户
     * @param ids
     * @return
     */
    @Override
    public boolean batchDel(List<String> ids) {
        return this.userMapper.batchDel(ids)>0;
    }

    /**
     * 用户配置角色关系
     * @param code
     * @param uId
     * @param roleIds
     * @return
     */
    @Override
    @Transactional
    public boolean updateRoleRel(String code,Long uId,List<Long> roleIds) {
        List<UserRoleRel> userRoleRels = userMapper.getRelByCode(code);
        //需要插入的
        List<UserRoleRel> newRels = new ArrayList<UserRoleRel>();
        //需要更新失效的
        List<UserRoleRel> invalidRels = new ArrayList<UserRoleRel>();
        //需要更新有效的
        List<UserRoleRel> validRels = new ArrayList<UserRoleRel>();

        if(userRoleRels != null && userRoleRels.size() >0){
            for (UserRoleRel rel : userRoleRels){
                if(roleIds.contains(rel.getRoleId())){
                    //包含
                    if(rel.getState() == 0){
                        //原有未激活的
                        UserRoleRel userRoleRel = new UserRoleRel();
                        userRoleRel.setState(StateEnum.Valid.getState());
                        userRoleRel.setUpdateUid(uId);
                        userRoleRel.setRoleId(rel.getRoleId());
                        userRoleRel.setUserCode(code);
                        validRels.add(userRoleRel);//塞入待激活list
                    }
                    //移除
                    roleIds.remove(rel.getRoleId());
                }else {
                    //不包含 使失效
                    UserRoleRel userRoleRel = new UserRoleRel();
                    userRoleRel.setState(StateEnum.Invalid.getState());
                    userRoleRel.setUpdateUid(uId);
                    userRoleRel.setRoleId(rel.getRoleId());
                    userRoleRel.setUserCode(code);
                    invalidRels.add(userRoleRel);
                }
            }

        }
        if(roleIds != null && roleIds.size()>0){
            for (Long roleId :roleIds){
                UserRoleRel rel = new UserRoleRel();
                rel.setState(StateEnum.Valid.getState());
                rel.setCreateUid(uId);
                rel.setUserCode(code);
                rel.setRoleId(roleId);
                newRels.add(rel);
            }
        }
        if(newRels.size()>0){
            userRoleMapper.batchAdd(newRels);
        }
        if(invalidRels.size()>0){
            userRoleMapper.batchInvalid(uId,invalidRels);
        }
        if(validRels.size()>0){
            userRoleMapper.batchValid(uId,validRels);
        }
        return true;
    }

    /**
     * 添加用户角色关系
     * @param code
     * @param uId
     * @param roleIds
     * @return
     */
    @Override
    @Transactional
    @CacheEvict(value="setting",cacheResolver = "settingCacheResolver",condition = "#result==true")
    public boolean addUserRole(String code,Long uId,List<Long> roleIds) throws BaseException{
        //需要插入的
        List<UserRoleRel> newRels = new ArrayList<UserRoleRel>();
        if(roleIds != null && roleIds.size() >0){
            for (Long roleId : roleIds) {
                UserRoleRel userRoleRel = new UserRoleRel();
                userRoleRel.setState(StateEnum.Valid.getState());
                userRoleRel.setUpdateUid(uId);
                userRoleRel.setRoleId(roleId);
                userRoleRel.setUserCode(code);
                newRels.add(userRoleRel);
            }
            return this.userRoleMapper.batchAdd(newRels) >0;
        }
        return false;
    }

    /**
     * 根据工号获取用户角色关系信息
     * @param userCode
     * @return
     */
    @Override
    @Cacheable(value="setting",cacheResolver = "settingCacheResolver",key = "'userrolerel_'+ #userCode", condition = "#result==true")
    public List<UserRoleRel> getRoleRelByUserCode(String userCode){
        return userMapper.getRoleRelByUserCode(userCode);
    }

    /**
     * 批量新增
     * @param users
     * @return
     */
    @Override
    public boolean batchAdd(List<User> users){
        return userMapper.batchAdd(users) > 0;
    }


    /**
     * 根据code列表查用户数据
     * @param codes
     * @return
     */
    @Override
    public List<User> queryByCodes(List<String> codes){
        return this.userMapper.queryByCodes(codes);
    }
}
